// Copyright (c) 2009-2011, chunquedong
//
// This file is part of ChunMap project
// Licensed under the GNU LESSER GENERAL PUBLIC LICENSE(Version >=3)
//
// History:
//   2011-09-23  Jed Young  Creation
//

using fwt
using gfx
using gfx2
using gfx2Imp
using concurrent

using chunmapDesktop
using chunmapData
using chunmapModel
using chunmapUtil
using chunmapView
using chunmapRaster

class Frame : Window
{
  MapCanvas mapCanvas
  LayerPane layerPane

  const static Str handle := Uuid().toStr
  const static |->| callback := |->|{Desktop.callAsync |->| { Actor.locals[handle]->renderMap; }}

  new make() : super()
  {
    mapCanvas = MapCanvas()
    title = "Chunmap"
    icon  = Image(`fan://chunmapFrame/res/x32/chunmap.png`)

    size = Size(1000, 600)
    menuBar = makeMenuBar
    layerPane = LayerPane(mapCanvas)

    content = EdgePane
    {
      top = makeToolBar
      left = InsetPane(5) { it.content = layerPane }
      center = mapCanvas
    }

    Actor.locals[handle] = mapCanvas
    Actor.locals["chunmapTaster.TileDataSource.callback"] = callback
  }

  Command undoCmd := Command.makeLocale(this.typeof.pod, "undo") |->| { mapCanvas.undo; mapCanvas.renderMap }
  Command redoCmd := Command.makeLocale(this.typeof.pod, "redo") |->| { mapCanvas.redo; mapCanvas.renderMap }

  Command openCmd := Command.makeLocale(this.typeof.pod, "open") |->|
  {
    File? file := FileDialog { it.mode=FileDialogMode.openFile; filterExts = ["*.cmp"] }.open(this)
    if (file == null) return

    if (file.uri.ext.lower == "cmp")
    {
      in := file.in
      mapCanvas.map.layers = in.readObj
      in.close
    }
    else
    {
      throw UnsupportedErr("unsupported $file.uri")
    }
    mapCanvas.fullView.renderMap
    layerPane.rebind
  }

  Command addDataCmd := Command.makeLocale(this.typeof.pod, "addData") |->|
  {
    File[]? files := FileDialog { it.mode=FileDialogMode.openFiles; filterExts = ["*.shp", "*.tab"] }.open(this)
    if (files == null) return

    files.each |file|
    {
      if (file.uri.ext.lower == "shp")
      {
        layer0 := VectorLayer.makeUri(file.uri)
        mapCanvas.layers.add(layer0)
      }
      else
      {
        echo("unsupported data type: $file.uri")
      }
    }
    mapCanvas.fullView.renderMap
    layerPane.rebind
  }

  Command saveCmd := Command.makeLocale(this.typeof.pod, "save") |->|
  {
    File file := FileDialog { it.mode=FileDialogMode.saveFile; filterExts = ["*.cmp"] }.open(this)
    file.writeObj(mapCanvas.layers, ["indent":2])
  }

  Command fullCmd := Command.makeLocale(this.typeof.pod, "full") |->| { mapCanvas.fullView.renderMap }
  Command selectCmd := Command.makeLocale(this.typeof.pod, "select") |->| { mapCanvas.setCurrentTool(SelectTool()) }
  Command panCmd := Command.makeLocale(this.typeof.pod, "pan") |->| { mapCanvas.setCurrentTool(PanTool()) }
  Command zoominCmd := Command.makeLocale(this.typeof.pod, "zoomin") |->| { mapCanvas.setCurrentTool(BoxZoomIn()) }
  Command disCmd := Command.makeLocale(this.typeof.pod, "dis") |->| { mapCanvas.setCurrentTool(DistanceTool()) }
  Command areaCmd := Command.makeLocale(this.typeof.pod, "edit") |->| { mapCanvas.setCurrentTool(AreaTool()) }

  **
  ** Build the menu bar
  **
  Menu makeMenuBar()
  {
    return Menu
    {
      Menu
      {
        text = "File";
        addCommand(openCmd)
        addCommand(saveCmd)
        MenuItem { text = "Exit"; onAction.add |->| { Env.cur.exit } },
      },
      Menu
      {
        text = "Layer"
        addCommand(addDataCmd)
        MenuItem { text = "AddGoogleMap"; onAction.add |e|{
          r := Dialog.openPromptStr(e.window, "Enter Uri:", "http://mt2.google.cn/vt/v=w2.116&hl=zh-CN&gl=cn")
          if(r == null) return
          layer := RasterLayer.makeUri(GDataSource#, r.toUri, callback)
          mapCanvas.layers.add(layer)
          mapCanvas.fullView.renderMap
          layerPane.rebind
        } },
        MenuItem { text = "AddWMS"; onAction.add |e|{
          r := Dialog.openPromptStr(e.window, "Enter Uri:", "http://localhost:8080")
          if(r == null) return
          layer := RasterLayer.makeUri(WmsDataSource#, r.toUri, callback)
          mapCanvas.layers.add(layer)
          mapCanvas.fullView.renderMap
          layerPane.rebind
        } },
        MenuItem { text = "AddTileMap"; onAction.add |e|{
          r := Dialog.openPromptStr(e.window, "Enter Uri:", "http://localhost:8080")
          if(r == null) return
          layer := RasterLayer.makeUri(TileDataSource#, r.toUri, callback)
          mapCanvas.layers.add(layer)
          mapCanvas.fullView.renderMap
          layerPane.rebind
        } },
      },
      Menu
      {
        text = "Help";
        MenuItem { text = "About"; onAction.add { Dialog.openInfo(this, "Chunmap. Copyright (c) 2009-2011, chunquedong") } },;
      },
    }
  }

  Widget makeToolBar()
  {
    return ToolBar
    {
      addCommand(openCmd)
      addCommand(addDataCmd)
      addSep
      Button { command = panCmd; it.mode = ButtonMode.radio; it.text = "" },
      Button { command = zoominCmd; it.mode = ButtonMode.radio; selected = true; it.text = "" },
      Button { command = selectCmd; it.mode = ButtonMode.radio; it.text = "" },
      Button { command = disCmd; it.mode = ButtonMode.radio; it.text = "" },
      Button { command = areaCmd; it.mode = ButtonMode.radio; it.text = "" },;
      addSep
      addCommand(fullCmd)
      addCommand(undoCmd)
      addCommand(redoCmd)
    }
  }
}